using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Drawing.Drawing2D;
using System.Diagnostics;

using BPMN.MainWindow;

namespace BPMN.MainWindow
{
    public class LaneList : IEnumerable<Lane>
    {

        List<Lane> lanes = new List<Lane>();

        public Lane this[int index]
        {
            get
            {
                if (index >= 0)
                {
                    return lanes[index];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                lanes[index] = value;
            }
        }

        public Lane this[string name]
        {
            get
            {
                for (int i = 0; i < lanes.Count; i++)
                {
                    if (lanes[i].Name == name)
                    {
                        return lanes[i];
                    }
                }
                return null;
            }
            set
            {
                for (int i = 0; i < lanes.Count; i++)
                {
                    if (lanes[i].Name == name)
                    {
                        lanes[i] = value;
                    }
                }
            }
        }

        public int Count
        {
            get
            {
                return lanes.Count;
            }
        }

        public void Add(Lane item)
        {
            lanes.Add(item);
        }

        public void Clear()
        {
            lanes.Clear();
        }

        public int GetIndex(string name)
        {
            for (int i = 0; i < lanes.Count; i++)
            {
                if (lanes[i].Name == name)
                {
                    return i;
                }
            }
            return -1;
        }

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return lanes.GetEnumerator();
        }

        #endregion

        #region IEnumerable<Lane> Members

        public IEnumerator<Lane> GetEnumerator()
        {
            return lanes.GetEnumerator();
        }

        #endregion
    }
    public class Pool : Figure
    {
        #region Fields
        LaneList lanes = new LaneList();
        int currentLaneIndex;
        #endregion
        public int CurrentLaneIndex
        {
            get
            {
                return currentLaneIndex;
            }
            set
            {
                if (currentLaneIndex >= 0)
                {
                    lanes[currentLaneIndex].State = FigureState.Unselected;
                }
                currentLaneIndex = value;
                if (currentLaneIndex >= 0)
                {
                    lanes[currentLaneIndex].State = FigureState.Selected;
                }
            }
        }
        public Lane CurrentLane
        {
            get
            {
                return lanes[currentLaneIndex];
            }
            set
            {
                lanes[currentLaneIndex] = value;
            }
        }
        public LaneList Lanes
        {
            get
            {
                return lanes;
            }
            set
            {
                lanes = value;
            }
        }
        public Pool(PointF location, SizeF size)
        {
            this.Location = location;
            this.Size = size;
            Random r = new Random();
            Lane lane = new Lane("Lane" + Lanes.Count + r.Next(1000), this, new PointF(this.Location.X + Variables.PoolTitleWidth, this.Location.Y), new SizeF(this.Size.Width - Variables.PoolTitleWidth, this.Size.Height));
            lanes.Add(lane);
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            if (this.State!= FigureState.Unselected)
            {
                bool laneSelectedFound = false;
                foreach (Lane lane in lanes)
                {
                    if (lane.State == FigureState.Selected)
                    {
                        laneSelectedFound = true;
                    }
                }
                if (!laneSelectedFound)
                {
                    graphics.FillRectangle(brush, offset.X + Location.X, offset.Y + Location.Y, Size.Width, Size.Height);
                }
            }
            else
            {
                graphics.FillRectangle(brush, offset.X + Location.X, offset.Y + Location.Y, Size.Width, Size.Height);
            }
            graphics.DrawRectangle(pen, offset.X + Location.X, offset.Y + Location.Y, Size.Width, Size.Height);
            graphics.DrawRectangle(pen, offset.X + Location.X, offset.Y + Location.Y, Variables.PoolTitleWidth, Size.Height);
            string displayName = Name;
            float titleSize = graphics.MeasureString(displayName, Variables.PoolTitleFont).Width;
            if (titleSize > Size.Height - 10)
            {
                float charWidth = (titleSize + 5) / Name.Length;
                displayName = Name.Remove((int)(Name.Length - (titleSize - Size.Height + 10) / charWidth));
                displayName += "...";
            }
            titleSize = graphics.MeasureString(displayName, Variables.PoolTitleFont).Width;
            graphics.RotateTransform(-90);
            graphics.DrawString(displayName, Variables.PoolTitleFont, Variables.PoolTitleBrush, new PointF(-Location.Y - (Size.Height + titleSize) / 2 - offset.Y, Location.X + offset.X));
            graphics.RotateTransform(90);
            foreach (Lane lane in lanes)
            {
                lane.Draw(graphics, pen, brush, offset);
            }
            if (this.State == FigureState.Resizing)
            {
               // DrawResizePoolHotSpot(graphics, ResizeBoundingBox, offset);
                for (int i = 0; i < lanes.Count; i++)
                {
                    DrawResizeLaneHotSpot(graphics, lanes[i].ResizeBoundingBox, offset);
                }
            }
        }
        public void DrawResizePoolHotSpot(Graphics graphics, RectangleF boundingBox, PointF offset)
        {
            Pen p = new Pen(Color.Black);
            graphics.DrawRectangle(p, boundingBox.X + offset.X, boundingBox.Y + offset.Y, boundingBox.Width, boundingBox.Height);
            p.Dispose();
        }
        public void DrawResizeLaneHotSpot(Graphics graphics, RectangleF boundingBox, PointF offset)
        {
            Pen p = new Pen(Color.Black);
            graphics.DrawRectangle(p, boundingBox.X + offset.X, boundingBox.Y + offset.Y, boundingBox.Width, boundingBox.Height);
            p.Dispose();
        }
        public override void UpdateSomeParametersLocation(PointF oldLocation)
        {
            PointF difference = new PointF(this.Location.X - oldLocation.X, this.Location.Y - oldLocation.Y);
            BoundingBox = new RectangleF(Location, Size);
           // ResizeBoundingBox = new RectangleF(Location.X + Size.Width / 2 - 15, Location.Y + Size.Height - 30, 30, 30);
            foreach (Lane lane in lanes)
            {
                lane.Location = new PointF(lane.Location.X + difference.X, lane.Location.Y + difference.Y);
                lane.BoundingBox = new RectangleF(lane.Location, lane.Size);
                if (lane.Path != null)
                {
                    lane.Path.Dispose();
                }
                lane.Path = new GraphicsPath();
                lane.Path.AddRectangle(lane.BoundingBox);
                lane.Region = new Region(lane.Path);
            }

        }
        public override void UpdateSomeParametersSize(SizeF newSize)
        {
            BoundingBox = new RectangleF(Location, Size);
           // ResizeBoundingBox = new RectangleF(Location.X + Size.Width / 2 - 15, Location.Y + Size.Height - 30, 30, 30);
            if (lanes.Count > 0)
            {
                lanes[lanes.Count - 1].Size = new SizeF(lanes[lanes.Count-1].Size.Width, this.Location.Y+this.Size.Height - lanes[lanes.Count - 1].Location.Y);
            }
        }
    }
}